
package com.powerunion.datacollection.report.excelreport.base.element;

import java.util.Date;

import com.powerunion.datacollection.report.excelreport.Logger;
import com.powerunion.datacollection.report.excelreport.base.BaseField;
import com.powerunion.datacollection.report.excelreport.base.ITempletContainer;
import com.powerunion.datacollection.report.excelreport.base.Parameter;
import com.powerunion.datacollection.report.excelreport.util.AnalyseTempletTool;

import jxl.write.WritableCell;

/**
 * 普通模板字段处理类,代表模板中的一个具体定义的字段类模板对象, 如$F{ds.field1},
 * $P{param1}等都被抽象成一个CommonField对象实例。
 * @author juny
 */
public class CommonField extends BaseField {
    private static Logger log = Logger.getLogger(CommonField.class);
    /**
     * @param container
     */
    public CommonField(ITempletContainer container) {
        super(container);
    }

    /*
     * (non-Javadoc)
     * @see excel.report.base.IElementWriter#setElementTempletValue(java.lang.String)
     */
    public void setElementTempletValue(String value) {
        var = ElementFactory.getVariableInstances(value);
        if (null == var) {
            log.error("Couldn't create the variable instance! -"
	                   + value);
        }
        StringBuffer s = new StringBuffer(AnalyseTempletTool
                .getElementDeclare(value));
        if (AnalyseTempletTool.haveVariableName(s)) {
            setName(AnalyseTempletTool.getVariableName(s));
        } else {
            setName(var.getName());
        }
    }

    /*
     * (non-Javadoc)
     * @see net.excel.report.base.BaseField#writeImpl(net.excel.report.base.Parameter)
     */
    public boolean writeImpl(Parameter param) throws Exception {
        if (null == var) {
            return false;
        }

        Object value = var.getValue();
        //modified date 2006-11-01 当返回值为null时，当前单元格设置为""字符串
        if(null == value){
            value = "";
        }
        
        WritableCell cell = param.wc;

        try {
            WritableCell retCell = copyCellByType(cell, 
            						value, 
            						param.destCol,
                    				param.destRow);
            if (null == retCell) {
                retCell = copyDefaultCell(param, value);
            }
            param.wc = retCell;
        } catch (Exception e) {
            log.error("Catch an exception while write a cell in col="
                    + cell.getColumn() + " row=" + cell.getRow() + " value is"
                    + value.toString() + " \n" + " error message:"
                    + e.getMessage(), e);
            return false;
        }
        return true;
    }
    
    /*
     * (non-Javadoc)
     * @see net.excel.report.base.BaseField#beforeWriteProcess(net.excel.report.base.Parameter)
     */
    protected void beforeWriteProcess(Parameter param){
        if(null != var){
            //初始化参数变量
            setParam(param);
        }
    }

    /**
     * 设置模板对象参数，通过参数模板对象知道自己应该从何处去取得具体的模板值
     * @param param
     */
    private void setParam(Parameter param) {
        if (!initialized) {
            //配置相应变量对象的初始化参数。
            var.setParam(param);
            initialized = true;
        }
    }

    /**
     * 拷贝一个单元格，新单元格的类型根据数据的类型来产生，
     * 并复制源单元格的格式化，边框等其他属性到新的单元格中。
     * @param cell
     * @param value
     * @param destCol
     * @param destRow
     * @return
     */
    private WritableCell copyCellByType(WritableCell cell, Object value,
			int destCol, int destRow) {
		WritableCell retCell = null;

		if (value instanceof Date) {
			retCell = copyCellByType(cell, value, CELL_TYPE_DATE, destCol,
					destRow);
		}

		if (value instanceof java.lang.Number) {
			retCell = copyCellByType(cell, value, CELL_TYPE_NUMBER, destCol,
					destRow);
		}

		return retCell;
	}

    public String toString() {
        if (null != var) {
            return var.toString();
        }
        return "null";
    }

    private Variable var = null;

    private boolean initialized = false;
}